package ru.surfstudio.graduate.activity;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.j256.ormlite.android.apptools.OrmLiteBaseActivity;

import ru.surfstudio.graduate.R;
import ru.surfstudio.graduate.bean.ChannelManager;
import ru.surfstudio.graduate.data.DatabaseHelper;
import ru.surfstudio.graduate.data.Feed;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class FeedViewActivity extends OrmLiteBaseActivity<DatabaseHelper> {
	
	public static final String FEED = "FEED";
	public static final String FEEDS_ID_LIST = "FEEDS_ID_LIST";
	
	private static final String TAG = "FeedViewActivity";
	
	private static final String TYPE_CONTENT = "text/html";
	private static final String CHARSET_ENCODING = "utf-8";
	private static final String META_TAG = 
		"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
	
	private String IMAGE_REGULAR = "\u003cimg ";
	private String IMAGE_REGULAR_NEW = "\u003cimg width=%s ";
	
	private ImageView favoriteIcon;
	private TextView nameText;
	private TextView authorText;
	private TextView dateText;
	private WebView feedView;
	
	private FeedViewActivityState state;

	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.feed_view_activity);
        
        state = (FeedViewActivityState) getLastNonConfigurationInstance();
        if (state == null) {
        	state = new FeedViewActivityState();
        } else {
        	state.attach(this);
        }
        if (state.feed == null)
        	state.feed = (Feed) getIntent().getSerializableExtra(FEED);
        if (state.feedIdList == null)
        	state.feedIdList = (List<Integer>) getIntent().getSerializableExtra(FEEDS_ID_LIST);
        
        favoriteIcon = (ImageView) findViewById(R.id.feed_view_favorite_image);
    	nameText = (TextView) findViewById(R.id.feed_view_name_feed_text);
    	authorText = (TextView) findViewById(R.id.feed_view_author_text);
    	dateText = (TextView) findViewById(R.id.feed_view_date_text);
    	
        feedView = (WebView) findViewById(R.id.feed_view_content_webview);
        feedView.getSettings().setJavaScriptEnabled(true);
        
        setFeedsUIData(state.feed);
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		
		state.detach();
	}
	
	@Override
    public Object onRetainNonConfigurationInstance() {
		state.saveFeedTask.detach();
        return state;
    }
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		new MenuInflater(this).inflate(R.menu.feed_view_option, menu);
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		menu.findItem(R.id.feed_view_to_favorite_menu_item)
				.setVisible(!state.feed.getFavorites());
		menu.findItem(R.id.feed_view_cancel_favorite_menu_item)
				.setVisible(state.feed.getFavorites());
		
		menu.findItem(R.id.feed_view_to_nonreaded_menu_item)
				.setVisible(state.feed.getReaded());
		menu.findItem(R.id.feed_view_to_readed_menu_item)
				.setVisible(!state.feed.getReaded());
		
		return super.onPrepareOptionsMenu(menu);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		switch (item.getItemId()) {
			case R.id.feed_view_to_favorite_menu_item:
				changeFavoriteStatus();
				break;
			case R.id.feed_view_cancel_favorite_menu_item:
				changeFavoriteStatus();
				break;
			case R.id.feed_view_search_menu_item:
				// TODO Auto-generated method stub
				break;
			case R.id.feed_view_to_nonreaded_menu_item:
				changeReadedStatus();
				break;
			case R.id.feed_view_to_readed_menu_item:
				changeReadedStatus();
				break;
			case R.id.feed_view_email_menu_item:
				sendEmail();
				break;
		}
		return super.onOptionsItemSelected(item);
	}
	

	public void onFavoriteIconClick(View v) {
		changeFavoriteStatus();
	}
	
	public void nextButtonClick(View v) {
		int id = findNextFeedId(true);
		if (id > -1)
			executeSwichFeedTask(id);
	}
	
	public void previousButtonClick(View v) {
		int id = findNextFeedId(false);
		if (id > -1)
			executeSwichFeedTask(id);
	}
	
	private void changeFavoriteStatus() {
		state.feed.setFavorites(!state.feed.getFavorites());
		executeSaveFeedTask();
		setFavoriteIcon();
	}

	private void setFavoriteIcon() {
		if (state.feed.getFavorites()) {
			favoriteIcon.setImageResource(R.drawable.star);
		} else {
			favoriteIcon.setImageResource(R.drawable.star_white);
		}
	}
	
	private void changeReadedStatus() {
		state.feed.setReaded(!state.feed.getReaded());
		executeSaveFeedTask();
	}
	
	private void sendEmail() {
		Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
        
        emailIntent.setType("text/html");
        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, 
        		new String[]{ getString(R.string.feed_view_email_address) });
        emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, 
        		getString(R.string.feed_view_email_subject, state.feed.getName()));
        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, state.feed.getContent());

        startActivity(Intent.createChooser(emailIntent, "Send mail..."));
	}
	
	private int findNextFeedId(boolean isNext) {
		if (!state.feedIdList.isEmpty() && state.feedIdList.contains(state.feed.getId())) {
			
			int firstId = Integer.valueOf(state.feedIdList.get(0));
			int lastId = Integer.valueOf(state.feedIdList.get(state.feedIdList.size() - 1));
	
			if (isNext && state.feed.getId() == firstId) {
				return lastId;
			} else if (!isNext && state.feed.getId() == lastId) {
				return firstId;
			} else {
				int indexRow = state.feedIdList.indexOf(state.feed.getId());
				if (isNext) {
					return state.feedIdList.get(indexRow - 1);
				}else {
					return state.feedIdList.get(indexRow + 1);
				}
			}
		}
		return -1;
	}
	
	private void executeSaveFeedTask() {
		state.saveFeedTask = new SaveFeedTask(this);
		state.saveFeedTask.execute();
	}
	
	private void executeSwichFeedTask(Integer nextFeedId) {
		if (state.swichFeedTask == null || state.swichFeedTask.isCancelled() ||
				state.swichFeedTask.getStatus().equals(AsyncTask.Status.FINISHED)) {
			
			state.swichFeedTask = new SwichFeedTask(this);
			state.swichFeedTask.execute(nextFeedId);
		}
	}
	
	private void setFeedsUIData(Feed feed) {
		if (feed == null)
			return;
		state.feed = feed;
		
		setTitle(state.feed.getChannelName());
    	nameText.setText(state.feed.getName());
    	authorText.setText(String.format(getString(R.string.feed_view_author_text), 
    			state.feed.getAuthor()));
    	dateText.setText(prepareDate(state.feed.getDate()));
    	
    	setFavoriteIcon();
    	
        String content = resizeImages(state.feed.getContent());
        feedView.loadData(META_TAG + content, TYPE_CONTENT, CHARSET_ENCODING);
        
        if (!state.feed.getReaded())
        	changeReadedStatus();
	}
	
	private String resizeImages(String data) {
		int width = getResources().getDisplayMetrics().widthPixels / 3;
		return data.replaceAll(IMAGE_REGULAR, String.format(IMAGE_REGULAR_NEW, width + "px"));
		
	}
	
	private String prepareDate(Date date) {
		Calendar dateCal = Calendar.getInstance();
		Calendar nowCal = Calendar.getInstance();
		dateCal.setTime(date);
		
		String dayDate = "";
		if (dateCal.get(Calendar.YEAR) == nowCal.get(Calendar.YEAR) &&
				dateCal.get(Calendar.DAY_OF_YEAR) == nowCal.get(Calendar.DAY_OF_YEAR)) {
			
			dayDate = getString(R.string.feed_view_date_today_text);
			
		} else {
			dayDate = formatDate("dd.MM.yy", date);
		}
		return String.format(getString(R.string.feed_view_date_text), dayDate, 
				formatDate("HH:mm", date));
	}
	
	private String formatDate(String formatStr, Date date) {
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		return format.format(date);
	}
	
	private class SaveFeedTask extends AsyncTask<Void, Void, Boolean> {

		private FeedViewActivity activity;
		
		public SaveFeedTask(FeedViewActivity activity) {
			attach(activity);
		}
		
		@Override
		protected Boolean doInBackground(Void... params) {
			try {
				if (activity != null) {
					ChannelManager channelManager = new ChannelManager(activity.getHelper());
					channelManager.updateFeed(activity.state.feed);
				}
				return true;
				
			} catch (SQLException e) {
				Log.e(TAG, e.getMessage(), e);
			} catch (Exception e) {
				Log.e(TAG, e.getMessage(), e);
			}
			return false;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			if (activity != null) {
				if (!result) {
					Toast.makeText(activity, R.string.database_error, Toast.LENGTH_LONG)
						.show();
					Log.w(TAG, getString(R.string.database_error));
				}
			}
		}
		
		public void detach() {
			activity = null;
		}
		
		public void attach(FeedViewActivity activity) {
			this.activity = activity;
		}
		
	}
	
	private class SwichFeedTask extends AsyncTask<Integer, Void, Feed> {

		private FeedViewActivity activity;
		
		public SwichFeedTask(FeedViewActivity activity) {
			attach(activity);
		}
		
		@Override
		protected Feed doInBackground(Integer... params) {
			try {
				Integer feedId = params[0];
				
				if (activity != null) {
					ChannelManager cManager = new ChannelManager(getHelper());
					return cManager.findFeed(feedId);
				}
			} catch (SQLException e) {
				Log.d(TAG, e.getMessage(), e);
			} catch (Exception e) {
				Log.d(TAG, e.getMessage(), e);
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(Feed result) {
			if (activity != null) {
				if (result != null) {
					setFeedsUIData(result);
				} else {
					Toast.makeText(activity, R.string.database_error, Toast.LENGTH_LONG).show();
				}
			}
		}
		
		public void detach() {
			activity = null;
		}
		
		public void attach(FeedViewActivity activity) {
			this.activity = activity;
		}
		
	}

	/** Activity state */
	private static class FeedViewActivityState {
		
		public SaveFeedTask saveFeedTask;
		
		public SwichFeedTask swichFeedTask;
		
		public Feed feed;
		
		public List<Integer> feedIdList;
		
		public void attach(FeedViewActivity activity) {
			if (saveFeedTask != null)
				saveFeedTask.attach(activity);
			if (swichFeedTask != null)
				swichFeedTask.attach(activity);
		}
		
		public void detach() {
			if (saveFeedTask != null)
				saveFeedTask.detach();
			if (swichFeedTask != null)
				swichFeedTask.detach();
		}
		
	}

}
